<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="https://unpkg.com/element-plus/dist/index.css" />
  <script src="https://unpkg.com/vue@next"></script>
  <script src="https://unpkg.com/element-plus"></script>
  <style>
    #Comment{
      display: flex;
      justify-content: flex-end;
      width:500px;
    }
    .comment-block{
      border:1px solid #d9d9d9;
      padding:10px;
      font-size: 14px;
      width:100%;
      box-sizing: border-box;
      color:#333;
    }
    .comment-block button {
      padding:0 5px;
    }
    .comment-block button:not(.danger):hover {
      color:#4da4fd;
    }
    .comment-container {
      padding:5px;
      width: 100%;
      box-sizing: border-box;
    }
    .comment{
      display: flex;
      flex-direction: column;
    }
    .comment header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      color:#827e7e;
      padding-top:5px;
    }
    .comment main{
      margin:6px 0;
      padding:0 5px;
      box-sizing: border-box;
      word-wrap: break-word;
      word-break:keep-all;
    }
    .comment footer{
      margin-left:15px;
    }
    .comment-container > .comment{
      padding-bottom: 10px;
      border-bottom: 1px solid #f0f0f0;
    }
    .user {
      margin-right:10px;
      font-weight: bold;
    }
    .user[data-type="self"]::after{
      content:'(自己)'
    }
    .time {
      font-size: 12px;

    }

    .comment-input {
      padding-top:15px;
      width:100%;
      height:100px;
      box-sizing: border-box;
      display: flex;
      flex-direction: column;
      justify-content: space-between;
    }
    .comment-input footer{
      display: flex;
      justify-content: flex-end;
      margin:0 10px;
    }
    .comment-edit footer{
      display: flex;
      justify-content: flex-end;
    }
    .el-input__wrapper{
      border-radius: 5px;
      background-color: #f1f6fb;
      box-shadow: none;
      font-size: 16px;
    }
    .input input{
      background-color: #f1f6fb;
    }
    .need-hover {
      visibility: hidden;
    }
    .hover-zone:hover .need-hover{
      visibility: visible;
    }

    .btn {
      padding:0 5px;
    }
    .btn:hover path{
      stroke:#51a8ff;
    }
  </style>
</head>
<body>

  <div id="Comment">
    <div class="comment-block" v-if="showCommentBlock">
      <section class="comment-container" >
        <comment v-for="c in comments" :comment="c" :id="userId" 
          @comment-to="updateCommentTo" 
          @update="updateComment"
          @delete="deleteComment"
        ></comment>
      </section>
      <section class="comment-input">
        <reply @send="sendComment" @cancel="updateCommentTo(0)" :to="commentTo"></reply>
      </section>
    </div>
    <el-button plain class="btn" @click="showCommentBlock = !showCommentBlock">
      <comment-icon></comment-icon>
    </el-button>
  </div>

  <script>
    const CommentIcon = {
      template:`
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="18" height="18">
        <g>
        <rect width="48" height="48" fill="rgba(130.05,125.97,125.97,1)" fill-opacity="0.01" stroke="none"></rect>
        <rect width="48" height="48" fill="rgba(130.05,125.97,125.97,1)" fill-opacity="0.01" stroke="none"></rect>
        <path d="M44 6H4V36H13V41L23 36H44V6Z" fill="none" stroke="rgba(130.05,125.97,125.97,1)" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path>
        <path d="M14 19.5V22.5" stroke="rgba(130.05,125.97,125.97,1)" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" fill="none"></path>
        <path d="M24 19.5V22.5" stroke="rgba(130.05,125.97,125.97,1)" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" fill="none"></path>
        <path d="M34 19.5V22.5" stroke="rgba(130.05,125.97,125.97,1)" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" fill="none"></path>
        </g>
      </svg>
      `
    }
    
    const Reply = {
      props:["to", "mode"],
      emits:['send', 'update', 'cancel'],
      computed:{
        placeholder(){
          const {to, mode} = this
          if(mode === 'edit') return to.commentContext
          return to.pid ? `回复 ${to.userName} :` : '请输入评论'
        }
      },
      watch:{
        to(newVal, oldVal){
          if(newVal.pid === oldVal.pid) return
          else this.newContext = ''
        }
      },
      data(){
        return {
          newContext:this.to.commentContext
        }
      },
      template:`
        <el-input size="large" class="input" :placeholder="placeholder" v-model="newContext"></el-input>
        <footer>
          <el-button text @click="handleSend">发送</el-button>
          <el-button text @click="handleCancel">取消</el-button>
        </footer>
      `,
      methods:{
        handleSend(){
          const { pid, commentContext } = this.to
          const cb = this.mode === 'edit' ? 'update' : 'send' 

          // 无需更新
          if(cb === 'update' && this.newContext === commentContext) {
            this.handleCancel()
            return
          }
          
          this.$emit(cb, pid, this.newContext)
          this.newContext = ''
          this.handleCancel()
        },
        handleCancel(){
          this.newContext = ''
          this.$emit('cancel')
        }
      }
    }
    
    const Comment = {
      name:'comment',
      components:{
        reply:Reply
      },
      props:['id','comment'],
      template:`
      <div class="comment">
        <section class="hover-zone">
          <header>
            <span>
              <span class="user" v-text="comment.userName"></span>
              <span class="time" v-text="comment.time"></span>
            </span>

            <span class="need-hover" v-if="!isEditing">
              <span v-if="comment.userId === id">
                <el-button text @click="toggleEdit(true)">编辑</el-button>
                <el-button text type="danger" class="danger" @click="$emit('delete', comment.pid)">删除</el-button>
              </span>
              <el-button v-else text @click="$emit('comment-to', comment.pid, comment.userName, comment.userId)">回复</el-button>
            </span> 
          </header>
          <main v-text="comment.commentContext" v-if="!isEditing"></main>
          <main v-else class="comment-edit">
            <reply 
              :to="comment" 
              @update="(pid, text) => $emit('update', pid, text)" 
              @cancel="toggleEdit(false)"
              mode="edit"
            />
          </main>
        </section>
        <footer>
          <comment v-for="sub in comment.subComments" 
            :comment="sub" :id="id" 
            @comment-to="(id, userName, userId) => $emit('comment-to', id, userName, userId)"
            @update="(pid, text) => $emit('update', pid, text)"
            @delete="(pid) => $emit('delete', pid)"
          />
        </footer>
    </div>
    `,
    data(){
      return {
        isEditing:false,
      }
    },
    methods:{
      toggleEdit(editing){
        this.isEditing = editing
      }
    }
    }

    // 调整 #Comment 的 width 即可调整评论框的大小
    const app = Vue.createApp({
      components:{
        comment:Comment,
        reply:Reply,
        commentIcon:CommentIcon
      },
      data() {
        return {
           showCommentBlock:false,
           userName:'孜然',
           userId: 123,
           fileId:987,
           commentTo:{
            pid:0,
            commentContext:''
           },
           comments:[
            {
              pid:1,
              userName:'孜然',
              userId:123,
              time:'2022-7-21 10:25',
              commentContext:'hello, world',
              subComments:[
                {
                  pid:11,
                  userName:'小明',
                  userId:456,
                  time:'2022-7-21 10:25',
                  commentContext:'ashaohogra',
                  subComments:[{
                    pid:111,
                    userName:'孜然',
                    userId:123,
                    time:'2022-7-21 10:25',
                    commentContext:'sdsghjjdsfghjfdshgsddngfdnfdngfn fdxxcvngdmhgfdmjhtdhjtrfdxjjytdxxvjytdxxcv nuytdxh54excxcvbnhgyjytredccvvnmgrtrdvvbnhjmjtrhgfda',
                  }]
                },
                {
                  pid:12,
                  userName:'孜然',
                  userId:123,
                  time:'2022-7-21 10:25',
                  commentContext:'sdsghjjdsfghjfdshgsddngfdnfdngfn fdxxcvngdmhgfdmjhtdhjtrfdxjjytdxxvjytdxxcv nuytdxh54excxcvbnhgyjytredccvvnmgrtrdvvbnhjmjtrhgfda',
                },
              ]
            },
            {
              pid:2,
              userName:'小红',
              userId:486136,
              time:'2022-7-21 10:25',
              commentContext:'sds ghjjds fghjf dshgs ddngfdn fdngfn fdxxcvngd mhgfdmjhtd hjt rfdxjjytd xxvjyt dx xcvn uytd xh54excxcv bnhgyjyt redccvvnmgrt rdvvb nhj mj trhgfd a',
            }
           ]
        }
      },
      methods: {
        // TODO 发送评论
        async sendComment(pid, commentContext){    
          this.updateCommentTo(0)
          // pid 评论的是哪条评论
          // commentContext 评论内容
          const userId = this.userId // 发送者
          const fileId = this.fileId // 文件的 id
          const body = {
              userId,
              commentContext,
              pid,
              // TODO fileId
            }

          console.log(body)
          const result = await fetch("/projetc/saveComment", {
            method:"POST",
            body
          })

          const res = await result.json()
            .then((res) => res)
            .catch((err) => console.log(err))
          
            console.log(res)

        },
        // TODO 修改评论
        async updateComment(pid, commentContext){
          // pid 修改的是哪条评论
          // commentContext 修改内容
          const userId = this.userId // 发送者
          const fileId = this.fileId // 文件的 id
          const body = {
              userId,
              commentContext,
              pid,
              // TODO fileId
            }

          console.log('[update]', body)
          const result = await fetch("/projetc/updateComment", {
            method:"POST",
            body
          })

          const res = await result.json()
            .then((res) => res)
            .catch((err) => console.log(err))
          
            console.log(res)

        },
        // TODO 删除评论
        async deleteComment(pid){
          // pid 删除的评论
          const fileId = this.fileId // 文件的 id
          const body = {
              pid,
              // TODO fileId
            }

          console.log('[delete]', body)

        },
        // 改变被评论的人
        updateCommentTo(pid, userName, userId){

          if(!pid) {
            this.commentTo = {
              pid:0,
              commentContext:''
            }
            return
          }
          this.commentTo = {
            pid,
            userName,
            userId,
            commentContext:'',
          }
          console.log(this.commentTo)
        }
      
      }
    })

    app.use(ElementPlus)
    app.mount('#Comment')
  </script>
</body>
</html>